package com.fujimana.rockincat.restree.web;

import java.util.Collections;
import java.util.HashSet;
import java.util.Set;

import com.fujimana.rockincat.restree.context.Context;

public class RestContextFactory {

	private static final RestContextFactory INSTANCE = new RestContextFactory();

	private RestContextFactory() {
	}

	public static RestContextFactory getInstance() {
		return INSTANCE;
	}

	public Context create(Context... ctx) {
		return new DelegateContext(ctx);
	}

	class DelegateContext implements Context {
		private Context[] ctxs;

		DelegateContext(Context... ctx) {
			ctxs = ctx;
		}

		@Override
		public Object get(String name) {
			for (Context c : ctxs) {

				if (c.isSet(name)) {
					return c.get(name);
				}
			}
			
			return null;
		}

		@Override
		public Set<String> getKeys() {
			Set<String> set = new HashSet<String>();

			for (Context c : ctxs) {
				set.addAll(c.getKeys());
			}

			return Collections.unmodifiableSet(set);
		}

		@Override
		public boolean isSet(String name) {
			for (Context c : ctxs) {

				if (c.isSet(name)) {
					return true;
				}
			}

			return false;
		}

		@Override
		public void remove(String name) {
			for (Context c : ctxs) {

				if (c.isSet(name)) {
					c.remove(name);
					return;
				}
			}
		}

		@Override
		public void set(String name, Object value) {
			for (Context c : ctxs) {

				if (c.isSet(name)) {
					c.set(name, value);
					return;
				}
			}
			
			ctxs[ctxs.length-1].set(name, value);
		}

		@Override
		public Object get(String name, Scope scope) {
			for (Context c : ctxs) {
				if(c.getScope() == scope) {
					return c.get(name);
				}
			}
			
			return null;
		}

		@Override
		public Set<String> getKeys(Scope scope) {
			for (Context c : ctxs) {
				if(c.getScope() == scope) {
					return c.getKeys();
				}
			}
			
			return null;
		}

		@Override
		public Scope getScope() {
			return null;
		}

		@Override
		public boolean isSet(String name, Scope scope) {
			for (Context c : ctxs) {
				if(c.getScope() == scope) {
					return c.isSet(name);
				}
			}
			
			return false;
		}

		@Override
		public void remove(String name, Scope scope) {
			for (Context c : ctxs) {
				if(c.getScope() == scope) {
					c.remove(name);
				}
			}
		}

		@Override
		public void set(String name, Object value, Scope scope) {
			for (Context c : ctxs) {
				if(c.getScope() == scope) {
					c.set(name, value);
				}
			}
		}

	}
}
